<template>
    <!-- 按钮选项组 -->
    <div class="flex flex-wrap gap-2 ml-2 mb-2">
        <!-- 调整行高 -->
        <el-tooltip effect="dark" content="调整行高" placement="bottom">
            <el-input-number style="width: 120px" v-model="rowHeight" :min="200" :max="280" :step="5" step-strictly />
        </el-tooltip>
        <!-- 搜索框+按钮 -->
        <el-input
            style="width: 180px"
            v-model="searchRoleValue"
            placeholder="请输入角色关键字查询"
            clearable
            @keydown.enter="searchRoleEvent"
            @clear="inputClearEvent"
        />
        <el-button :icon="Search" @click="searchRoleEvent">搜索</el-button>
        <!-- 选项 -->
        <el-button-group>
            <el-button type="primary" @click="addRoleEvent" :icon="Plus">添加角色</el-button>
            <el-button type="primary" @click="getAllRoleEvent" :icon="Refresh">刷新</el-button>
            <el-button type="danger" @click="deleteRoleEvent" :icon="DeleteFilled">删除角色</el-button>
        </el-button-group>
    </div>
    <div style="height: calc(100vh - 120px)">
        <el-auto-resizer>
            <template #default="{ height, width }">
                <FTableV2
                    v-model="selected"
                    :data="data"
                    :width="width"
                    :height="height"
                    :row-height="rowHeight"
                    :other-column="otherColumn"
                    :disable="disable"
                ></FTableV2>
            </template>
        </el-auto-resizer>
    </div>

    <!-- 添加/编辑角色权限弹窗 -->
    <el-dialog v-model="updateRolesPermissionVisible" :close-on-click-modal="false" width="80%" :show-close="false">
        <!-- 标题 -->
        <template #header="{ close, titleId, titleClass }">
            <div class="my-header">
                <h4 :id="titleId" :class="titleClass">编辑权限组</h4>
                <el-button type="danger" @click="close">
                    <el-icon class="el-icon--left"><CircleCloseFilled /></el-icon>
                    关闭
                </el-button>
            </div>
        </template>
        <!-- 角色英文 -->
        <el-input class="mb-2" v-model="role" placeholder="请输入角色英文" clearable />
        <!-- 角色名称 -->
        <el-input v-model="roleName" placeholder="请输入角色名称" clearable />
        <div class="w-full flex flex-wrap justify-center mb-4 mt-4">
            <el-transfer
                class="w-full flex justify-center items-center"
                v-model="selectedPermission"
                :data="permissionList"
                :titles="['权限列表', '已选权限']"
                filterable
                :filter-method="filterPermissionMethod"
                filter-placeholder="搜索关键字"
                @change="permissionChangeEvent"
            />
            <el-button v-if="!addFlag" @click="updateRolesPermissionSubmitEvent">提交</el-button>
            <el-button v-if="addFlag" @click="addRolesPermissionSubmitEvent">提交</el-button>
        </div>
    </el-dialog>
</template>

<script setup lang="tsx">
import { addRolesPermission, deleteRolesPermission, getAllRole, updateRolesPermission } from '@api/system/index';
import { Column, ElButton, ElTag, TransferDirection, TransferKey } from 'element-plus';
import { Search, Refresh, Plus, DeleteFilled } from '@element-plus/icons-vue';
import { useDictionaryStore } from '@/store/modules/dictionary';
import { checkRole } from '@/utils/permission';
import { getAllPermission } from '@api/system/index';
import { CircleCloseFilled } from '@element-plus/icons-vue';

onMounted(() => {
    generateDisableColumn();
    getAllRoleEvent();
});

/* ******************************通用属性/方法****************************** */
// 字典仓库
const useDictionary = useDictionaryStore();
// 表格选中数据
const selected = reactive<string[]>([]);
// 获取用户数据
const getAllRoleEvent = () => {
    // 清空数据
    dataCache.splice(0);
    data.splice(0);
    selected.splice(0);
    // 获取所有系统用户
    getAllRole().then((res) => {
        // 加工成表格数据
        res.data.forEach((item, index) => {
            item.checked = false;
            item.order = index + 1;
            item.editing = false;
            data.push(item);
            dataCache.push(item);
        });
    });
};

/* ******************************搜索栏属性/方法****************************** */
const searchRoleValue = ref('');
// 搜索事件
const searchRoleEvent = () => {
    if (searchRoleValue.value == '') {
        // 原始数据
        data.length = 0;
        dataCache.forEach((item) => {
            data.push(item);
        });
    } else {
        // 筛选数据
        data.length = 0;
        dataCache.forEach((item) => {
            if (item.role.includes(searchRoleValue.value) || item.description.includes(searchRoleValue.value)) {
                data.push(item);
            }
        });
    }
};
// 输入框清空事件
const inputClearEvent = () => {
    // 原始数据
    data.length = 0;
    dataCache.forEach((item) => {
        data.push(item);
    });
};

/* ******************************组件el-table-v2 表格属性****************************** */
// 表格数据
const data = reactive<AjaxResponse['roleData']>([]);
// 缓存数据
let dataCache: AjaxResponse['roleData'] = [];
// 禁用列
const disable = reactive<string[]>([]);
// 表格独有的column
const otherColumn = reactive<{ [key: string]: Column<any> }>({
    permissions: {
        key: 'permissions',
        dataKey: 'permissions',
        width: 1150,
        align: 'center',
        title: '权限组',
        cellRenderer: ({ rowData, column }) => {
            // 权限组编辑事件
            const onClick = () => {
                // 选中角色
                selectedRole.value = rowData.role;

                // 加载所有权限
                getAllPermission().then((res) => {
                    permissionList.length = 0;
                    res.data.forEach((item) => {
                        permissionList.push({
                            key: item._id,
                            label: item.description,
                            disabled: item.permission === 'root:root' ? true : false,
                        });
                    });
                });
                
                // 加载已选权限
                selectedPermission.value = rowData[column.dataKey!].map((i: any) => i._id);

                // 显示弹窗
                updateRolesPermissionVisible.value = true;
            };

            // 遍历每个组，显示对应的角色名称
            return (
                <div>
                    <div class={'flex flex-wrap gap-1'}>
                        {rowData[column.dataKey!].map((i: any) => {
                            return (
                                <ElTag class={'ml-1 mr-1'} type={'primary'}>
                                    {i.description}
                                </ElTag>
                            );
                        })}
                    </div>
                    <ElButton size={'small'} text type={'warning'} onClick={onClick}>
                        编辑
                    </ElButton>
                </div>
            );
        },
    },
    description: {
        key: 'description',
        dataKey: 'description',
        title: '说明',
        width: 200,
        align: 'center',
        cellRenderer: ({ rowData }) => {
            return <div>{rowData.description}</div>;
        },
    },
});
// 生成禁用列 -- 根据字典提供的权限加工otherColumn对象生成禁用列表
const generateDisableColumn = () => {
    // 遍历所有字段
    for (const key in otherColumn) {
        if (Object.prototype.hasOwnProperty.call(otherColumn, key)) {
            // 获取key在字典中的数据
            const { definition, roles } = useDictionary.getDictionaryUseField(key);
            // 判断是否为空
            if (definition == '') {
                disable.push(key);
                continue;
            }
            // 判断当前用户是否有权限查看该字段
            if (!checkRole(roles)) {
                disable.push(key);
            }
        }
    }
};
// 表格高度
const rowHeight = ref(200);

/* ******************************添加角色权限属性/方法****************************** */
// 添加角色的英文
const role = ref('');
// 添加角色的名称
const roleName = ref('');
// 添加角色的标识
const addFlag = ref(false);
// 添加角色事件
const addRoleEvent = () => {
    // 更改标识
    addFlag.value = true;
    // 清空已选权限
    selectedPermission.value.length = 0;
    // 打开dialog
    updateRolesPermissionVisible.value = true;
    // 加载所有权限
    getAllPermission().then((res) => {
        permissionList.length = 0;
        res.data.forEach((item) => {
            permissionList.push({
                key: item._id,
                label: item.description,
                disabled: item.permission === 'root:root' ? true : false,
            });
        });
    });
};
// 添加角色权限提交事件
const addRolesPermissionSubmitEvent = () => {
    // 校验角色名称是否为空
    if (roleName.value === '') {
        ElMessage.error('请输入角色名称');
        return;
    }
    // 校验已选权限是否为空
    if (selectedPermission.value.length === 0) {
        ElMessage.error('请选择权限');
        return;
    }
    // 提交数据
    addRolesPermission(role.value, roleName.value, selectedPermission.value).then((res) => {
        // 关闭弹窗
        updateRolesPermissionVisible.value = false;
        ElMessage.success(res.message);
        getAllRoleEvent();
        addFlag.value = false;
    });
};

/* ******************************修改角色权限属性/方法****************************** */
// 更新角色权限dialog
const updateRolesPermissionVisible = ref(false);
// 所有权限列表
const permissionList = reactive<
    {
        key: string;
        label: string;
        disabled: boolean;
    }[]
>([]);
// 已选角色
const selectedRole = ref<string>();
// 已选权限
const selectedPermission = ref<string[]>([]);
// 过滤权限方法
const filterPermissionMethod = (query: string, item: any) => {
    return item.label.includes(query);
};
// 需要被上传的权限
const uploadPermission = reactive<string[]>([]);
// 修改角色权限事件
const permissionChangeEvent = (value: TransferKey[], _direction: TransferDirection, _movedKeys: TransferKey[]) => {
    // 清空上传的权限
    uploadPermission.length = 0;
    // 更新需要上传的权限
    value.forEach((item) => {
        uploadPermission.push(item as string);
    });
};

// 更新角色权限提交事件
const updateRolesPermissionSubmitEvent = () => {
    // 提交数据
    updateRolesPermission(selectedRole.value!, uploadPermission).then((res) => {
        // 关闭弹窗
        updateRolesPermissionVisible.value = false;
        ElMessage.success(res.message);
        getAllRoleEvent();
    });
};

/* ******************************删除角色权限属性/方法****************************** */
// 删除角色事件
const deleteRoleEvent = () => {
    if (selected.length !== 1) {
        ElMessage.error('请选择一条要删除的角色');
        return;
    }

    // 确认删除
    ElMessageBox.confirm('确定删除选中的角色吗？', '删除确认', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
    }).then(() => {
        // 提交删除请求
        deleteRolesPermission(selected[0]).then((res) => {
            ElMessage.success(res.message);
            getAllRoleEvent();
        });
    });
};
</script>

<style scoped lang="scss">
.my-header {
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    gap: 16px;
}
</style>
